<template>
  <div class="box">
    <span v-if="msgNum > 0" class="icon-num">{{ msgNum }}</span>
    <el-popover
      trigger="click"
      :width="width"
      placement="bottom"
      @show="showPopover"
      @after-enter="showComplete">
      <template>
        <el-tabs v-model="activeName">
        <!-- 通知的内容 -->
        <el-tab-pane :label="`${item}(${nums[index]})`" :name="index" v-for="(item, index) in nameAndType" :key="index">
          <template v-if="listData">
            <div v-for="(ii, jj) in listData[index]" :key="index + jj + ''" class="info">
              <!--未读消息判断 只显示 5 条-->
              <template v-if="jj < 5">
                <div class="info_title" @click="depositInfo(ii)">{{ ii.noticeTitle }}</div>
                <dict-tag class="info_priority" :options="dict.type.sys_notice_priority" :value="ii.priority"/>
                <div class="info_time">{{ ii.published }} 发布</div>
                <el-divider class="xian" />
              </template>
            </div>
          </template>
          <el-button size="small" style="width: 100%;" @click="goNewsPage">查看更多</el-button>
        </el-tab-pane>
      </el-tabs>
      </template>
      <!-- 弹出窗显示的元素 -->
      <template slot="reference">
        <slot name="showDOM">
          <span class="iconfont icon-lingdang"></span>
        </slot>
      </template>
    </el-popover>

    <!-- 查看消息对话框 -->
    <el-dialog :visible.sync="dialogVisible" :fullscreen="dialogFull" width="40%">
      <template slot="title">
        <div class="dialog_slot_title">
          <span class="slot_title"> {{ "通知消息" }} </span>
          <i :class="['slot_icon', dialogFull ? 'iconfont icon-quxiaoquanping_o' : 'iconfont icon-quanping_o']" @click="dialogFull? dialogFull=false: dialogFull=true" />
        </div>
      </template>
      <div class="msg_info">
        <div class="title">{{ infoOneData.noticeTitle }}</div>
        <div class="info">
          <span v-if="infoOneData.publisher"> 发布人：{{ infoOneData.publisher }} </span>
          <span v-if="infoOneData.published"> 发布时间：{{ infoOneData.published}} </span>
        </div>
        <el-divider v-if="infoOneData.publisher || infoOneData.published"></el-divider>
        <div v-html="infoOneData.noticeContent"></div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getUnreadMsgApi, readMsgApi } from '@/api/system/userMsg'
import UserMessage from "@/views/system/userMessage/index.vue"
import { getUserId } from '@/api/system/user'
import { newWebSocket } from '@/utils/webSocket.js'


let ws = null
export default {
  dicts: ['sys_notice_priority'],
  props: {
    // 类别所代表的唯一标识 和 标签页的类别
    nameAndType: {
      type: Object,
      default: function() {
        return {
          '1': '通知',
          '2': '系统消息'
        }
      }
    },
    // 标识的字段名称
    nameType: {
      type: String,
      default: 'noticeType'
    },
    // 弹出窗的宽度
    width: {
      type: Number,
      default: 300
    },
    // 内部对话框显示
    insideDia: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      userId: null,
      activeName: '',
      listData: null,
      dialogVisible: false,
      dialogFull: false,
      infoOneData: {},
      msgNum: 0,
      nums: {}
    }
  },
  mounted() {
    this.getId()
    this.getMsgList()
  },
  methods: {
    // 获取当前 id
    getId() {
      getUserId().then((res) => {
        this.userId = res.data
      }).finally(() => {
        this.webSockt(this.userId)
      })
    },
    // 开启 websocket
    webSockt(userId, toUserId) {
      // 判断浏览器是否支持 websocket 即时通讯
      if('WebSocket' in window) {
        newWebSocket.init({
          url: process.env.VUE_APP_WS_URL + `/websocket/${userId}`, // 自己的ws 地址
          userId: userId,
          toUserId: toUserId,
          onopen: (msg, data) => {
            // console.log(msg, data)
          },
          onmessage: (data) => {
            // 判断后端返回的是不是连接成功
            if (data == '连接成功' || data == 'ping' || data.includes('发送消息')) return
            // 将后端返回的数据转化
            let eData = JSON.parse(data)
            // 判断后端返回的是否为 空
            if (eData.length > 0 && eData[0]['num'] == 0) eData = []
            // 后端返回正确的数据进行处理
            if (Array.isArray(eData)) this.listData = this.convertData(eData)
          },
          onclose: (data) => {
            // console.log(data)
          }
        })
      } else {
        this.$message.warning('您的浏览器不支持顶部未读消息自动获取，请手动刷新！')
      }
    },
    // 通过标题点击 查看
    depositInfo(item) {
      // 判断对话框是否用组件内 对话框 显示
      if (this.insideDia) {
        this.infoOneData = item
        this.dialogVisible = true
      } else {
        // 改变外部对话框显示状态 和 改变数据
        this.$emit('updateVisible', true)
        this.$emit('updataShowMsg', item)
      }
        // 将消息改成已读状态
       readMsgApi(item.tnoticeUserId).then((res) => {
        if(res.code === 200) {
          this.getMsgList()
        }
      }).finally(() => {
        // 刷新我的消息页面列表
        UserMessage.methods.getList()
      })
    },
    // 获取未读消息
    getMsgList() {
      getUnreadMsgApi().then((res) => {
        if(res.code == 200) {
          this.listData = this.convertData(res.data)
        }
      })
    },
    // 将数据进行分类处理
    convertData(data) {
      let tempData = {}
      this.msgNum = data.length
      data.forEach(item => {
        if(tempData[item[this.nameType]] == undefined) {
          tempData[item[this.nameType]] = []
          tempData[item[this.nameType]].push(item)
        } else {
          tempData[item[this.nameType]].push(item)
        }
      });
      // 统计分类下有几条数据
      let arr = Object.keys(this.nameAndType)
      arr.forEach(item => {
        this.nums[item] = tempData[item] == undefined ? '0' : tempData[item].length
      })
      return tempData
    },
    // 去消息页面
    goNewsPage() {
      if(this.$route.fullPath == '/system/userMessage') return
      this.$router.push({
        path: '/system/userMessage'
      })
    },
    // 显示弹出窗 - 解决弹出窗初始没有横线样式 1
    showPopover() {
      this.activeName = ''
    },
    // 显示弹出窗动画加载完毕 - 解决弹出窗初始没有横线样式 2
    showComplete() {
      this.activeName = Object.keys(this.nameAndType)[0]
    }
  }
}
</script>

<style scoped>
.box {
  position: relative;
  display: inline-block !important;
  padding: 15px 8px;
  transform: scale(1.2);
}
.info .info_title {
  color: #1890ff !important;
  cursor:pointer;
}
.info .info_priority {
  text-align: right !important;
}
.info .info_time {
  color: rgba(0, 0, 0, 0.45);
}
.info .xian {
  margin-top: 10px;
  margin-bottom: 10px;
}

.MsgInfo {
  position: relative;
}
.icon-num {
  display: block;
  position: absolute;
  top: 4px;
  right: -2px;
  padding: 3px 3px;
  margin-top: 2px;
  color: #fff;
  width: 20px;
  border-radius: 15px;
  background-color: #f5222d;
  line-height: 1;
  text-align: center;
  font-size: 10px;
  overflow: hidden;
  transform: scale(0.8);
}
</style>

<style lang="scss" scoped>
.msg_info{
  .title {
    margin-bottom: 8px;
    font-size: 16px;
    color: rgba(0, 0, 0, 0.85);
  }
  .info {
    font-size: 14px;
    color: rgba(0, 0, 0, 0.45);
  }
}
</style>
